/**
  * @file         sfc_mem_ringbuf.h
  * @brief
  * @note
  * @author       lixinliang
  * @date         2021-06-08
  * @version      1.0
  *
  * @par          修改日志
  * <table>
  * <tr><th>Date        <th>Version          <th>Author                        <th>Description
  * <tr><td>2021-06-08  <td>1.0              <td>lixinliang@hopechart.com      <td>创建初始版本
  * @copyright    杭州鸿泉物联网技术股份有限公司
  */
#ifndef _SFC_MEM_RINGBUF_H_
#define _SFC_MEM_RINGBUF_H_

#include "base_types/base_types.h"
#include "base_types/base_errors.h"

#ifdef __cplusplus
extern "C" {
#endif

// 在cortexm3和cortexm4中，bool，uint8，uint16，uint32 读写是原子操作（无论是否4字节对齐），也就说不用加锁。
typedef uint32_t TSFCAtomicUsize;

typedef struct TSFCMemRingbufTag TSFCMemRingbuf;
struct TSFCMemRingbufTag
{
    uint8_t  *buff_begin_;      ///< buff 起始位置
    uint8_t  *buff_end_;        ///< buff 结束位置
    uint8_t  *wr_pos_;          ///< 写入位置指针
    uint8_t  *rd_pos_;          ///< 读取位置指针
    TSFCAtomicUsize wr_size_;   ///< 写入字节数 原子操作
    TSFCAtomicUsize rd_size_;   ///< 可读字节数 原子操作
};

int32_t TSFCMemRingbufCreate(TSFCMemRingbuf *self, uint8_t *buff, int32_t buff_size);

void TSFCMemRingbufDestroy(TSFCMemRingbuf *self);

void TSFCMemRingbufReset(TSFCMemRingbuf *self);

int32_t TSFCMemRingbufPush(TSFCMemRingbuf *self, const void *data, int32_t data_size);

int32_t TSFCMemRingbufPop(TSFCMemRingbuf *self, void *buff, int32_t buff_size);

int32_t TSFCMemRingbufDrop(TSFCMemRingbuf *self, int32_t buff_size);

int32_t TSFCMemRingbufPeek(TSFCMemRingbuf *self, void *buff, int32_t buff_size);

static inline uint32_t TSFCMemRingbufCapacity(TSFCMemRingbuf *self) {return  self->buff_end_ - self->buff_begin_;};

static inline uint32_t TSFCMemRingbufBytes(TSFCMemRingbuf *self) {return  self->wr_size_ - self->rd_size_;};

static inline uint32_t TSFCMemRingbufLeftSpace(TSFCMemRingbuf *self) {return  TSFCMemRingbufCapacity(self) - TSFCMemRingbufBytes(self);};

static inline bool TSFCMemRingbufIsFull(TSFCMemRingbuf *self) {return TSFCMemRingbufCapacity(self) == TSFCMemRingbufBytes(self);};

static inline bool TSFCMemRingbufIsEmpty(TSFCMemRingbuf *self) {return  TSFCMemRingbufBytes(self) == 0;};

#ifdef __cplusplus
} // extern "C" {
#endif

#endif	// _SFC_MEM_RINGBUF_H_
